package com.woniuxy.java106crm.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.java106crm.request.ResponseResult;
import com.woniuxy.java106crm.util.JWTUtil;
import com.woniuxy.java106crm.util.TokenEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Component
public class AuthFilter extends OncePerRequestFilter {
    @Resource
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        log.debug("过滤");
        //获取token
        String token = request.getHeader("Authorization");
//        log.debug(token);
        //通过token获取用户id
        if(token != null){
            TokenEnum verify = JWTUtil.verify(token);
            //校验token
            if(verify == TokenEnum.TOKEN_BAD){
                //去登陆
                gologin(response);
                return;

            }else if(verify == TokenEnum.TOKEN_EXPIRE){
                //过期，去登陆
                // 过期应该生成一个新的token，返回给前端，下次请求就是携带新的token过来
                token = JWTUtil.generateToken(JWTUtil.getuid(token),JWTUtil.getAccount(token));
                //将新的token放入redis
//                redisTemplate.opsForValue().set(token, "");
                //普通数据通过return返回，token通过响应头返回
                response.setHeader("Authorization", token);
                //暴露头，告诉浏览器别过滤这个头，让前端程序能够拿到头
                response.setHeader("Access-Control-Expose-Headers","Authorization");
            }
            String account = JWTUtil.getAccount(token);
            //保存用户名
            request.getSession().setAttribute("account",account);
//            log.debug(account);
            //通过用户id查询用户信息
            UserDetails userDetails = userDetailsService.loadUserByUsername(account);
//            log.debug("{}",userDetails);
            //
            request.getSession().setAttribute("uid",JWTUtil.getuid(token));
            //将信息封装成authtication对象放入security上下文中
            //1。用户信息
            //2.密码
            //3.所有角色权限信息
            UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(upat);
        }
        //放行
        filterChain.doFilter(request,response);
    }
    private void gologin(HttpServletResponse response) throws IOException {
        ResponseResult<Boolean> result = new ResponseResult<>();
        result.setCode(403);//403-没登陆
        result.setMessage("请登录");
        result.setData(false);
        //设置响应头
        response.setContentType("application/json;charset=utf-8");
        //将对象转换成JSON并返回
        String json = new ObjectMapper().writeValueAsString(result);
        response.getWriter().write(json);
    }
}
